package com.hsgene.order.service.impl;

import com.hsgene.common.util.date.SimpleDateUtils;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.order.condition.SettlementExportCondition;
import com.hsgene.order.constants.ExportType;
import com.hsgene.order.domain.reconciliation.ReconciliationConditionDto;
import com.hsgene.order.domain.reconciliation.ReconciliationListInfo;
import com.hsgene.order.domain.reconciliation.ReconciliationListTotalInfoDto;
import com.hsgene.order.domain.reconciliation.ReconciliationPayAgencyInfo;
import com.hsgene.order.persistence.ReconciliationRepository;
import com.hsgene.order.service.ReconciliationService;
import com.hsgene.order.service.api.OrderPayService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

/**
 * 业务对账service
 *
 * @author wxf
 * @date 2018/11/7 15:30
 **/
@Service
public class ReconciliationServiceImpl implements ReconciliationService {

    /**
     * Log
     */
    private static Logger LOGGER = LogManager.getLogger(ReconciliationServiceImpl.class);

    @Resource
    private ReconciliationRepository reconciliationRepository;

    @Resource
    private OrderPayService orderPayService;

    @Resource(name = "defaultThreadPool")
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * 获取业务对账列表
     *
     * @param conditionDto 条件参数
     * @return
     */
    @Override
    public ReconciliationListTotalInfoDto getReconciliation(ReconciliationConditionDto conditionDto, Integer offset,
                                                            Integer size) {
        //获取数据库已付款订单
        List<ReconciliationListInfo> listInfos = reconciliationRepository.getReconciliation(conditionDto, offset, size);
        //获取总数
        Integer sumCount = reconciliationRepository.getReconciliationSumCount(conditionDto);
        ReconciliationListTotalInfoDto totalInfoDto = new ReconciliationListTotalInfoDto();
        totalInfoDto.setInfos(listInfos);
        if (sumCount == null) {
            totalInfoDto.setSumCount(0);
            totalInfoDto.setTotalPage(0);
            return totalInfoDto;
        }
        totalInfoDto.setSumCount(sumCount);
        totalInfoDto.setTotalPage(sumCount % size == 0 ? sumCount / size : sumCount / size + 1);
        return totalInfoDto;
    }

    /**
     * 获取导出信息
     *
     * @param exportCondition 导出信息id
     * @return
     */
    @Override
    public List<ReconciliationListInfo> getExportInfo(SettlementExportCondition exportCondition) {
        //选择行为空，说明导出全部，否则导出选中行
        if (ExportType.SELECTED.getType().equals(exportCondition.getExportType())) {
            return reconciliationRepository.getExportInfoByIds(exportCondition.getExportRowIds());
        }
        return reconciliationRepository.getExportInfo(exportCondition);
    }

    /**
     * 执行对账
     *
     * @param paySerialNumbers 支付流水号
     * @param time             对账时间
     */
    @Override
    public Boolean excuteReconciliation(List<String> paySerialNumbers, Date time) {
        try {
            List<Future> futures = new ArrayList<>();
            for (String number : paySerialNumbers) {
                Future<Boolean> future = taskExecutor.submit(new QueryTask(orderPayService, number, time,
                        reconciliationRepository));
                futures.add(future);
            }
            for (Future f : futures) {
                Boolean b = (Boolean) f.get();
                if (!b) {
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            LOGGER.error("reconciliation task is error...", e);
            return false;
        }
    }

    /**
     * 获取支付机构
     *
     * @return
     */
    @Override
    public List<ReconciliationPayAgencyInfo> getPayAgencyInfo() {
        return reconciliationRepository.getPayAgencyInfo();
    }
}

class QueryTask implements Callable<Boolean> {

    /**
     * Log
     */
    private static Logger LOGGER = LogManager.getLogger(QueryTask.class);

    private OrderPayService orderPayService;

    private String payOrderId;

    private Date time;

    @Resource
    private ReconciliationRepository reconciliationRepository;

    public QueryTask(OrderPayService orderPayService, String payOrderId, Date time, ReconciliationRepository
            reconciliationRepository) {
        this.orderPayService = orderPayService;
        this.payOrderId = payOrderId;
        this.time = time;
        this.reconciliationRepository = reconciliationRepository;
    }

    @Override
    public Boolean call() {
        try {
            ApiResult<Map<String, Object>> result = orderPayService.queryPayOrder(null, payOrderId);
            if (result.getCode() != 200) {
                return false;
            }
            Map<String, Object> map = result.getData();
            if (map == null) {
                return false;
            }
            Map<String, Object> payInfoMap = (Map<String, Object>) map.get("result");
            if (payInfoMap == null) {
                return false;
            }
            Double amount = Double.valueOf(payInfoMap.get("amount").toString())/100;
            LOGGER.info("query order pay info, payNo :" + payOrderId + ",amount:" + amount);
            //对比数据库
            return reconciliationRepository.checkUpdateReconciliation(payOrderId, amount, time);
        } catch (Exception e) {
            LOGGER.error("对账失败...",e);
            return false;
        }
    }
}

